package com.chen.authority.common.util;

import com.chen.authority.common.constant.SysConstant;
import com.chen.authority.entity.TreeEntity;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 树形结构 工具类
 *
 * @author chengy
 * @date 2023/9/20
 */
public class TreeUtil {

    /**
     * 构建树形结构数据
     *
     * @param id    父节点id
     * @param nodes 节点数据
     * @return 树节点
     */
    public static <T extends TreeEntity> List<T> build(Integer id, List<T> nodes) {
        // 构建顶级树
        if (id == SysConstant.ROOT) {
            return nodes.stream()
                    .filter(node -> node.getParentId().equals(SysConstant.ROOT))
                    .peek(node -> node.setChildren(build(node.getId(), nodes)))
                    .collect(Collectors.toList());
        }
        // 构建多级树
        return nodes.stream()
                .filter(node -> node.getParentId().equals(id))
                .peek(node -> node.setChildren(build(node.getId(), nodes)))
                .collect(Collectors.toList());
    }

    /**
     * 构建树形结构数据
     *
     * @param trees 来源数据
     * @param nodes 节点数据
     * @return 树节点
     */
    public static <T extends TreeEntity> List<T> build(List<T> trees, List<T> nodes) {
        return trees.stream()
                .anyMatch(node -> node.getParentId() == SysConstant.ROOT) ?
                trees.stream()
                        .filter(node -> node.getParentId().equals(SysConstant.ROOT))
                        .peek(node -> node.setChildren(build(node.getId(), nodes)))
                        .collect(Collectors.toList()) :
                trees.stream()
                        .peek(node -> node.setChildren(build(node.getId(), nodes)))
                        .collect(Collectors.toList());
    }

    /**
     * 去除子节点（防止构建过程中节点的重复出现）
     *
     * @param nodes 节点数据
     */
    public static <T extends TreeEntity> void removeSubNodes(List<T> nodes) {
        for (int i = 0; i < nodes.size(); i++) {
            Integer id = nodes.get(i).getId();
            nodes.removeIf(node -> node.getParentId().equals(id));
        }
    }

}
